/*!
   @file   Brush.cpp
   @author Ben Herila (ben@herila.net)
   @author Evan Wallace (evan.exe@gmail.com)
   @date   Fall 2010

   @brief
     Implementation of a brush that smudges the image on the canvas as
   the mouse is dragged. You should fill this file in for the Brush
   assignment.

*/

#include <iostream>
#include <CS123Common.h>

#include "SmudgeBrush.h"
#include "Canvas2D.h"

using namespace std;


SmudgeBrush::SmudgeBrush(BGRA color, int flow, int radius) : QuadraticBrush(color, flow, radius)
{
    // @TODO: [BRUSH] Initialize any memory you are going to use here. Hint - you are going to
    //       need to store temporary image data in memory. This might be a good place to
    //       allocate that memory.
    int side_len = 2*m_radius+1;
    BGRA * tempPick = new BGRA[side_len*side_len];
    makeMask();
}


SmudgeBrush::~SmudgeBrush()
{
    delete [] tempPick;
    // @TODO: [BRUSH] Be sure not to leak memory!

}



//! create a mask with a distribution of your choice (probably want to use quadratic for best results)
void SmudgeBrush::makeMask()
{
    // @TODO: [BRUSH] Set up the mask for your brush here. For this brush you will probably want
    //        to use a quadratic distribution for the best results. Linear or Gaussian would
    //        work too, however. Feel free to paste your code from the Linear or Quadratic brushes
    //        or modify the class inheritance to be able to take advantage of one of those class's
    //        existing implementations. The choice is yours!
    //
}

//! Picks up paint from the canvas before drawing begins.
void SmudgeBrush::pickUpPaint(int x, int y, Canvas2D* canvas)
{
    int width = canvas->width();
    int height = canvas->height();
    int rowstart = max(0,y-m_radius);
    int rowend = min(y+m_radius+1,height);
    int colstart = max(0,x-m_radius);
    int colend = min(x+m_radius+1,width);
    int rowcounter;
    int colcounter;
    int t_index = 0;
    for(rowcounter=rowstart; rowcounter<rowend; rowcounter++)
    {
        for(colcounter=colstart; colcounter<colend; colcounter++)
        {
            BGRA* pix = canvas->data();
            int index = rowcounter*width+colcounter;
            tempPick[t_index].r = pix[index].r;
            tempPick[t_index].g = pix[index].g;
            tempPick[t_index].b = pix[index].b;
            t_index++;
        }
    }

    // @TODO: [BRUSH] Perform the "pick up paint" step described in the assignment handout here.
    //        In other words, you should store the "paint" under the brush mask in a temporary
    //        buffer (which you'll also have to figure out where and how to allocate). Then,
    //        in the paintOnce() method, you'll paste down the paint that you picked up here.
    //

}

void SmudgeBrush::paintOnce(int mouse_x, int mouse_y, Canvas2D* canvas)
{
    // @TODO: [BRUSH] Here, you'll need to paste down the paint you picked up in
    //        the previous method. Be sure to take the mask into account! You can
    //        ignore the alpha parameter, but you can also use it (smartly) if you
    //        would like to.

    // now pick up paint again...
    pickUpPaint(mouse_x, mouse_y, canvas);

    int width = canvas->width();
    int height = canvas->height();
    int rowstart = max(0,mouse_y-m_radius);
    int rowend = min(mouse_y+m_radius+1,height);
    int colstart = max(0,mouse_x-m_radius);
    int colend = min(mouse_x+m_radius+1,width);
    int rowcounter;
    int colcounter;
    int t_index = 0;
    for(rowcounter=rowstart; rowcounter<rowend; rowcounter++)
    {
        for(colcounter=colstart; colcounter<colend; colcounter++)
        {
            BGRA* pix = canvas->data();
            int index = rowcounter*width+colcounter;
            int cr = pix[index].r;
            int cg = pix[index].g;
            int cb = pix[index].b;
            pix[index].r = tempPick[t_index].r*mask*m_flow+cr*(1-m_flow*mask);
            pix[index].g = tempPick[t_index].g*mask*m_flow+cg*(1-m_flow*mask);
            pix[index].b = tempPick[t_index].b*mask*m_flow+cb*(1-m_flow*mask);
            t_index++;
        }
    }


}


